package md.system;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import jakarta.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.UUID;

/**分布式数据库只能用UUID才会有好性能。
 * 顺序数字 编码。应用自己管理序列数字生成。
 * 配置表：
 * 根据业务需求和性能综合考虑：
 * 序号只能应用程序自己做，尽量避免共享使用同样的序号生成器，身份证编码那样的可能是直接查询最大数字然后+1模式解决。
 * 有些编码需要 递增的： 插入新的ROW就自动生成编号
 * 不好用@Column(updatable =false, columnDefinition ="SERIAL4 DEFAULT nextval('sequence_repno')" ) 前提条件是sequence_repno必须另外创建。
 *  @Generated(GenerationTime.INSERT)   不是@Id注解的其它字段递增序列生成器。
 *  @Column(updatable =false, columnDefinition ="bigint default nextval('sequence_repno')" ) 额外创立管理sequence也烦人。
 *  注解方式必须额外创建sequence后才能用。  SERIAL类型=数字不会顺序递增的；
 *  这么做法不会漏掉某个顺序数字也不会重复的。就是并发取序号的性能很差了。最好拆解并发连接，或者集中代理机制一个链接一次拿去好多个序号二次分配给被代理的二级代理分发客户。
 *  多客户并发读写同一个记录的冲突，访问大大影响性能，要是改成单车道顺序访问的话，访问能够快速通过而提高性能，并发事务等于相互砸场子吧。
 *  NewSQL时代 ID应该使用UUID在DB客户环节生成的。
* */
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Getter
@Setter
public class Sequence {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;
    /**序列生成器名字
     * */
    @Column(unique = true)
    @NotNull
    private String  name;
    /**递增的数值序号
     * 多个客户同时访问同一条记录会大大降低性能不可行！应该改用数据库提供的专有Sequence机制:CRDB数据库应该有专门的优化措施。
     * */
    private Long  lno;
}


/* 比较3种顺序数字编码生成器： #这3个办法实际上都比较慢，并发访问竞争引起的，读写同一个记录东西冲突损失并发性。
1,厂家建议模式：按时间排序且不会出现漏号的计数编码模式INSERT INTO cnt(val) SELECT max(val)+1 FROM cnt：性能差，CRDB数据库占用cpu高，磁盘倒是不算太繁忙：测试结果中等性能。
2,直接用单条记录读取+1来替代数据库nextval('sequence_repno')的方案：也较慢，并发性能低,磁盘利用率很高，数据库对cpu占用较低:测试结果最差了，事务冲突严重。
3,利用数据库自带SQL-sequence来做的方案，alter sequence sequence_ cache 50;测试结果是好的,cache 5漏号率可以忍受;默认cache 1基本没漏号但是性能最差。
第三方案同时采用alter sequence SQL-sequence cache 10;速度较快=53条/s，同时漏号率也比较低。
【瓶颈】CockroachDB的写入磁盘，磁盘队列长度>1甚至超过5都有，平均2.1的；系统瓶颈是磁盘随机写入性能，主要是IOPS指标。
文档 https://www.cockroachlabs.com/docs/v21.2/create-sequence.html  https://www.cockroachlabs.com/docs/v21.2/sql-faqs#how-do-i-auto-generate-unique-row-ids-in-cockroachdb
*/
